from machine import Pin
import bluetooth
import struct

SERVICE_UUID = '6E400001-B5A3-F393-E0A9-E50E24DCCA9E'
CHARACTERISTIC_UUID_RX = '6E400002-B5A3-F393-E0A9-E50E24DCCA9E'

class BLESimplePeripheral:
    def __init__(self, ble):
        self._ble = ble
        self._ble.active(True)
        self._ble.irq(self._irq)

        ((self._handle_tx,), (self._handle_rx, self._value_handle_rx)) = self._ble.gatts_register_services((
            (
                SERVICE_UUID,
                (
                    (bluetooth.UUID(CHARACTERISTIC_UUID_TX), bluetooth.FLAG_READ | bluetooth.FLAG_NOTIFY,),
                    (bluetooth.UUID(CHARACTERISTIC_UUID_RX), bluetooth.FLAG_WRITE,)
                )
            ),
        ))

        self._connections = set()
        self._write_callback = None

    def _irq(self, event, data):
        if event == bluetooth.EVT_GAP_CONNECTED:
            conn_handle, _, _ = data
            print("Connected")
            self._connections.add(conn_handle)
        elif event == bluetooth.EVT_GAP_DISCONNECTED:
            conn_handle, _, _ = data
            print("Disconnected")
            self._connections.remove(conn_handle)
        elif event == bluetooth.EVT_GATTS_WRITE:
            conn_handle, value_handle = data
            if value_handle == self._value_handle_rx and self._write_callback:
                value = self._ble.gatts_read(value_handle)
                self._write_callback(value.decode())

    def send(self, data):
        for conn_handle in self._connections:
            self._ble.gatts_notify(conn_handle, self._handle_tx, data.encode())

    def on_write(self, callback):
        self._write_callback = callback

def demo():
    def on_rx_data(rx_data):
        print("Received:", rx_data)
        esp.send(f"Echo: {rx_data}")

    esp = BLESimplePeripheral(bluetooth.BLE())
    esp.on_write(on_rx_data)

    while True:
        pass

demo()